import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

public class HttpUtils {

    private static final int CONNECTION_TIME_OUT = 2000;//连接超时时间
    private static final int SOCKET_TIME_OUT = 2000;//读写超时时间
    private static final int MAX_IDLE_CONNECTIONS = 30;// 空闲连接数
    private static final long KEEP_ALLIVE_TIME = 60000L;//保持连接时间

    private OkHttpClient okHttpClient;
    private volatile static HttpUtils httpUtils;

    public static HttpUtils getInstance(){
        if(httpUtils == null){
            synchronized (HttpUtils.class){
                if(httpUtils == null){
                    httpUtils = new HttpUtils();
                }
            }
        }
        return httpUtils;

    }

    public static HttpUtils getInstance(int connectionTimeOut,int socketTimeOut){
        if(httpUtils == null){
            synchronized (HttpUtils.class){
                if(httpUtils == null){
                    httpUtils = new HttpUtils(connectionTimeOut,socketTimeOut);
                }
            }
        }
        return httpUtils;

    }
    public HttpUtils(){
        System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");
        ConnectionPool connectionPool = new ConnectionPool(MAX_IDLE_CONNECTIONS,KEEP_ALLIVE_TIME, TimeUnit.MILLISECONDS);
        this.okHttpClient = new OkHttpClient()
                .newBuilder()
                .readTimeout(SOCKET_TIME_OUT, TimeUnit.MILLISECONDS)
                .writeTimeout(SOCKET_TIME_OUT, TimeUnit.MILLISECONDS)
                .connectionPool(connectionPool)
                .retryOnConnectionFailure(false) //自动重连设置为false
                .connectTimeout(CONNECTION_TIME_OUT,TimeUnit.MILLISECONDS)
                .addInterceptor(new RetryIntercepter(3)) //重试拦截器3次
                .addNetworkInterceptor(new NetworkIntercepter()) //网络拦截器，统一打印日志
                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory(),new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                })
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())//配置
                .build();
    }

    public HttpUtils(int connectionTimeOut,int socketTimeOut){
        System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");
        ConnectionPool connectionPool = new ConnectionPool(MAX_IDLE_CONNECTIONS,KEEP_ALLIVE_TIME, TimeUnit.MILLISECONDS);
        this.okHttpClient = new OkHttpClient()
                .newBuilder()
                .readTimeout(socketTimeOut, TimeUnit.MILLISECONDS)
                .writeTimeout(socketTimeOut, TimeUnit.MILLISECONDS)
                .connectionPool(connectionPool)
                .retryOnConnectionFailure(false) //自动重连设置为false
                .connectTimeout(connectionTimeOut,TimeUnit.MILLISECONDS)
                .addInterceptor(new RetryIntercepter(3)) //重试拦截器3次
                .addNetworkInterceptor(new NetworkIntercepter()) //网络拦截器，统一打印日志
                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory(),new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                })
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())//配置
                .build();
    }

    public Response sendRequest(Request request) throws Exception {
        return this.okHttpClient.newCall(request).execute();
    }
}
